package com.xzakota.minesweeper.widget;

import com.xzakota.minesweeper.R;
import com.xzakota.minesweeper.controller.GameResource;
import com.xzakota.minesweeper.model.GameModel;
import com.xzakota.minesweeper.model.Observable;
import com.xzakota.minesweeper.model.Observer;
import com.xzakota.minesweeper.util.ImageUtils;

import javax.swing.*;
import java.awt.*;

/**
 * 游戏数据信息展示视图
 * 包括 游戏标记地雷数、时间消耗
 * 
 * @author Xzakota
 */
public class GameInfoPanel extends JPanel implements Observer {
    // 默认图标资源
    private static final Icon[] NUM_ICONS = new ImageIcon[11];
    private static Icon ICON_CONTROL_MINE;
    private static Icon ICON_CONTROL_TIME;

    // 子视图
    private final JLabel[] mineAmountLabels;
    private final JLabel[] timeCounterLabels;

    // 游戏数据
    public int playTime = 0;
    private int mineAmount = 0;
    private int themeType = 0;
    private int gameStatus;

    public GameInfoPanel(GameModel model) {
        setOpaque(false);
        setBorder(
                BorderFactory.createCompoundBorder(BorderFactory.createLoweredSoftBevelBorder(),
                        BorderFactory.createEmptyBorder(3, 3, 3, 3))
        );
        setLayout(new BorderLayout());
        mineAmountLabels = createMineCounterView();
        timeCounterLabels = createTimeCounterView();
        themeType = model.getThemeType();
        model.addObserver(this);
    }

    /**
     * 加载默认资源
     */
    public static void loadResource() {
        NUM_ICONS[0] = GameResource.getIconResource(R.Icon.NUM_0);
        NUM_ICONS[1] = GameResource.getIconResource(R.Icon.NUM_1);
        NUM_ICONS[2] = GameResource.getIconResource(R.Icon.NUM_2);
        NUM_ICONS[3] = GameResource.getIconResource(R.Icon.NUM_3);
        NUM_ICONS[4] = GameResource.getIconResource(R.Icon.NUM_4);
        NUM_ICONS[5] = GameResource.getIconResource(R.Icon.NUM_5);
        NUM_ICONS[6] = GameResource.getIconResource(R.Icon.NUM_6);
        NUM_ICONS[7] = GameResource.getIconResource(R.Icon.NUM_7);
        NUM_ICONS[8] = GameResource.getIconResource(R.Icon.NUM_8);
        NUM_ICONS[9] = GameResource.getIconResource(R.Icon.NUM_9);
        NUM_ICONS[10] = GameResource.getIconResource(R.Icon.NUM_SPLIT);

        ICON_CONTROL_MINE = ImageUtils.changeIcon(GameResource.getIconResource(R.Icon.CONTROL_MINE_COUNT), 40, 40);
        ICON_CONTROL_TIME = ImageUtils.changeIcon(GameResource.getIconResource(R.Icon.CONTROL_TIME), 40, 40);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof GameModel model) {
            if (model.getThemeType() != themeType) {
                themeType = model.getThemeType();
                updateMineLeftView(model.currentMineLeft);
                updateTimeView(playTime);
            }
            if (mineAmount != model.currentMineLeft) {
                updateMineLeftView(model.currentMineLeft);
            }
            if (playTime != model.playTime) {
                updateTimeView(model.playTime);
            }
            if (gameStatus != model.gameStatus) {
                gameStatus = model.gameStatus;
            }
        }
    }

    private JLabel[] createMineCounterView() {
        return createCounterView(ICON_CONTROL_MINE, BorderLayout.WEST, false);
    }

    private JLabel[] createTimeCounterView() {
        return createCounterView(ICON_CONTROL_TIME, BorderLayout.EAST, true);
    }

    private JLabel[] createCounterView(Icon icon, String constraints, boolean isReverseOrder) {
        JPanel counterRootPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 7, 0));
        counterRootPanel.setOpaque(false);
        JPanel childPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        childPanel.setBorder(BorderFactory.createLoweredBevelBorder());
        JLabel[] labels = new JLabel[3];
        for (int i = 0; i < 3; i++) {
            JLabel label = new JLabel(NUM_ICONS[0]);
            childPanel.add(label);
            labels[i] = label;
        }
        if (isReverseOrder) {
            counterRootPanel.add(childPanel);
            counterRootPanel.add(new JLabel(icon));
        } else {
            counterRootPanel.add(new JLabel(icon));
            counterRootPanel.add(childPanel);
        }
        add(counterRootPanel, constraints);
        return labels;
    }

    private void updateMineLeftView(int amount) {
        if (amount < 0) {
            amount = -amount;
            mineAmountLabels[0].setIcon(NUM_ICONS[10]);
            mineAmountLabels[1].setIcon(NUM_ICONS[amount / 10]);
            mineAmountLabels[2].setIcon(NUM_ICONS[amount % 10]);
        } else {
            mineAmountLabels[0].setIcon(NUM_ICONS[amount / 100]);
            mineAmountLabels[1].setIcon(NUM_ICONS[amount % 100 / 10]);
            mineAmountLabels[2].setIcon(NUM_ICONS[amount % 10]);
        }
        mineAmount = amount;
    }

    public void updateTimeView(int time) {
        timeCounterLabels[0].setIcon(NUM_ICONS[time / 100]);
        timeCounterLabels[1].setIcon(NUM_ICONS[time % 100 / 10]);
        timeCounterLabels[2].setIcon(NUM_ICONS[time % 10]);
        playTime = time;
    }
}
